#include "shmcop.h"
#include <unistd.h>
#include <QSystemSemaphore>

extern int gIWho;


ShmCop::ShmCop():shmL2N(SHMKEY_L2N),
                                        shmN2L(SHMKEY_N2L),
                                        semL2N_Con(SEMKEY_L2N_Con,0),
                                        semL2N_Pro(SEMKEY_L2N_Pro,1),
                                        semN2L_Con(SEMKEY_N2L_Con,0),
                                        semN2L_Pro(SEMKEY_N2L_Pro,1)
{
    if(!shmL2N.create(SHMSIZE))
    {
        printf("shmL2N create failed:%s\n",shmL2N.errorString().toStdString().c_str());
    }
    if(!shmN2L.create(SHMSIZE))
    {
         printf("shmN2L create failed:%s\n",shmN2L.errorString().toStdString().c_str());
    }
    shmL2N.attach();
    if(shmL2N.isAttached())
    {
        printf("shmL2N attached successfully\n");
    };
    shmN2L.attach();
    if(shmN2L.isAttached())
    {
        printf("shmN2L attached successfully\n");
    };    
}

ShmCop::~ShmCop()
{
    if(shmL2N.detach())
    {
        printf("shmL2N deattached successfully\n");
    }
    if(shmN2L.detach())
    {
        printf("shmN2L deattached successfully\n");
    }
}

void ShmCop::SendData(QByteArray &data,shmDirection d)
{
    int size;
    if(d == L2N)//write direction
    {
        if(!shmL2N.isAttached())
        {
            return;
        }
        semL2N_Pro.acquire();
        size = data.size();
        size = qMin(size,shmL2N.size());
        shmL2N.lock();
        memcpy((char*)shmL2N.data(),data.data(),size);
        shmL2N.unlock();
        semL2N_Con.release();
    }
    else if(d == N2L)
    {
        if(!shmN2L.isAttached())
        {
            return;
        }
        semN2L_Pro.acquire();
        size = data.size();
        size = qMin(size,shmN2L.size());
        shmN2L.lock();
        memcpy((char*)shmN2L.data(),data.data(),size);
        shmN2L.unlock();    
        semN2L_Con.release();
    }
}

void ShmCop::run()
{
    while(1)
    {
        if(gIWho == PRO_L)
        {
            semN2L_Con.acquire();
            shmN2L.lock();
            buffer.setData((char*)shmN2L.constData(),shmN2L.size());
            memset((char*)shmN2L.data(),0,shmN2L.size());
            emit dataArrived((const QByteArray &)buffer.data());
            shmN2L.unlock();   
            semN2L_Pro.release();
        }
        else if(gIWho == PRO_N)
        {
            semL2N_Con.acquire();
            shmL2N.lock();
            buffer.setData((char*)shmL2N.constData(),shmL2N.size());
            memset((char*)shmL2N.data(),0,shmL2N.size());
            emit dataArrived((const QByteArray &)buffer.data());
            shmL2N.unlock();
            semL2N_Pro.release();
        }
    }
}





